/*=============================================================================
PostProcessDOF : depth of field post processing
Copyright (c) 2001 Crytek Studios. All Rights Reserved.

Revision history:
* 23/02/2005: Re-factored/Converted to CryEngine 2.0 by Tiago Sousa
* Created by Tiago Sousa

=============================================================================*/

#include "StdAfx.h"
#include "DriverD3D.h"
#include "I3DEngine.h"
#include "D3DPostProcess.h"

#pragma warning(disable: 4244)

/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////

SDepthOfFieldParams CDepthOfField::GetParams()
{
	SDepthOfFieldParams pParams;

	bool bGameDof = IsActive();

	float fFocusRange = m_pFocusRange->GetParam();
	float fMaxCoC = m_pMaxCoC->GetParam();  
	float fBlurAmount = m_pBlurAmount->GetParam();
	
	float fTodFocusRange = (CRenderer::CV_r_dof ==2)? m_pTimeOfDayFocusRange->GetParam() : 0;
	float fTodBlurAmount = (CRenderer::CV_r_dof ==2)? m_pTimeOfDayBlurAmount->GetParam() : 0;
#if defined(DIRECT3D10) && !defined(PS3)
	// Hack to reduce amount of blur for transparent/particles with full view depth behind them
	fTodBlurAmount = min(fTodBlurAmount, 0.4f);
#endif

	float fUserFocusRange = m_pUserFocusRange->GetParam();
	float fUserFocusDistance = m_pUserFocusDistance->GetParam();
	float fUserBlurAmount = m_pUserBlurAmount->GetParam();
	float fFrameTime = clamp_tpl<float>(gEnv->pTimer->GetFrameTime()*3.0f, 0.0f, 1.0f); 

	if( bGameDof )
		fUserFocusRange = fUserFocusDistance = fUserBlurAmount = 0.0f;

	m_fUserFocusRangeCurr += (fUserFocusRange - m_fUserFocusRangeCurr) * fFrameTime;
	m_fUserFocusDistanceCurr += (fUserFocusDistance - m_fUserFocusDistanceCurr) * fFrameTime;
	m_fUserBlurAmountCurr += ( fUserBlurAmount - m_fUserBlurAmountCurr) * fFrameTime;

	pParams.bGameMode = false;
	if( bGameDof )
	{
		// For gameplay dof, game code setting up independently near/far focus planes and additionally might use a focus mask

	  if(fFocusRange<0.0f)
	  {
			pParams.bGameMode = true;
	    float fFocusMin = 0.4f;//m_pFocusMin->GetParam();
	    float fFocusMax = m_pFocusMax->GetParam();
	    float fFocusLimit = m_pFocusLimit->GetParam();

	    // near blur plane distance, far blur plane distance, focus plane distance, blur amount
	    pParams.vFocus=Vec4(fFocusMin, fFocusLimit, fFocusLimit - fFocusMax, fBlurAmount);   
	  }
	  else
	  {
	    float fFocusRange_ = m_pFocusRange->GetParam();
	    float fFocusDistance = m_pFocusDistance->GetParam();

	    pParams.vFocus=Vec4(-fFocusRange_*0.5f, fFocusRange_*0.5f, fFocusDistance, fBlurAmount);    
	  }
	}
	else
	{
		// For non-gameplay mode, we use time of day values for far dof, blended with regular dof params

	  // near blur plane distance, far blur plane distance, focus plane distance, blur amount
	  static float s_fTodFocusRange = 0.0f;
	  static float s_fTodBlurAmount = 0.0f;
	  bool bUseGameSettings = (m_pUserActive->GetParam() )? true: false;

	  if( bUseGameSettings )
	  {
	    s_fTodFocusRange += (m_fUserFocusRangeCurr - s_fTodFocusRange) * fFrameTime;
	    s_fTodBlurAmount += (m_fUserBlurAmountCurr - s_fTodBlurAmount) * fFrameTime;

			// near blur plane distance, far blur plane distance, focus plane distance, blur amount
	    pParams.vFocus=Vec4(-m_fUserFocusRangeCurr*0.5f, m_fUserFocusRangeCurr*0.5f, m_fUserFocusDistanceCurr, m_fUserBlurAmountCurr);   
	  }
	  else
	  {
	    s_fTodFocusRange += (fTodFocusRange*2.0f - s_fTodFocusRange) * fFrameTime;
	    s_fTodBlurAmount += (fTodBlurAmount - s_fTodBlurAmount) * fFrameTime;

	    pParams.vFocus=Vec4(-s_fTodFocusRange*0.5f, s_fTodFocusRange*0.5f, 0, s_fTodBlurAmount);   
			//vParams=Vec4(-5, 1000, 00, 2);//s_fTodBlurAmount);   
	  }
	}

	pParams.vMinZParams.x = m_pFocusMinZ->GetParam();
	pParams.vMinZParams.y = m_pFocusMinZScale->GetParam();
	pParams.vMinZParams.z = pParams.vMinZParams.w = 0.0f;
		
	pParams.pMaskTex = 0;
	pParams.fMaskBlendAmount = 1.0;
	if( m_pUseMask->GetParam() )
		pParams.pMaskTex = const_cast<CTexture *> (static_cast<CParamTexture*>(m_pMaskTex)->GetParamTexture());

	// masked blur has higher priority than usual dof mask
	if( m_pMaskedBlurAmount->GetParam() )
	{
		pParams.fMaskBlendAmount = m_pMaskedBlurAmount->GetParam();
		pParams.pMaskTex = const_cast<CTexture *> (static_cast<CParamTexture*>(m_pMaskedBlurMaskTex)->GetParamTexture());
	}

	return pParams;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////

void CDepthOfField::Render()
{
  PROFILE_LABEL_PUSH( "DEPTH OF FIELD" );

	gRenDev->m_cEF.mfRefreshSystemShader("DepthOfField", CShaderMan::m_shPostDepthOfField);

  uint64 nSaveFlagsShader_RT = gRenDev->m_RP.m_FlagsShader_RT;
  gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0]|g_HWSR_MaskBit[HWSR_SAMPLE1]|g_HWSR_MaskBit[HWSR_SAMPLE2]|g_HWSR_MaskBit[HWSR_SAMPLE3]);
  
  int iTempX, iTempY, iWidth, iHeight;
  gcpRendD3D->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight);

  PROFILE_SHADER_START

  float fPrevDist = 0, fPrevMaxCoC = 0, fPrevFocusRange = 0, fPrevBlurAmount = 0, fPrevFocusMin = 0, fPrevFocusMax = 0;
  float fPrevFocusLimit = 0, fPrevUseMask = 0;

  float fFocusRange = m_pFocusRange->GetParam();
  float fMaxCoC = m_pMaxCoC->GetParam();  
  float fBlurAmount = m_pBlurAmount->GetParam();

	SDepthOfFieldParams pDofParams = GetParams();

  ///////////////////////////////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////
  {
    // Copy depth into backbuffer alpha channel    

    bool bGameDof = IsActive();
		
    if( CRenderer::CV_r_dof == 3)
      gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; 
     
    float fUseMask = m_pUseMask->GetParam();
    if(pDofParams.bGameMode)
    { 
      // Special case for gameplay
      if( fUseMask )        
      {
        static CCryNameTSCRC TechName("CopyDepthToAlphaBiased");
        GetUtils().ShBeginPass(CShaderMan::m_shPostDepthOfField, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);
      }
      else
      {
        static CCryNameTSCRC TechName("CopyDepthToAlphaBiasedNoMask");
        GetUtils().ShBeginPass(CShaderMan::m_shPostDepthOfField, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);            
      }
    }
    else
    {
      // For cinematics (simplified interface, using only focus distance/range)
      static CCryNameTSCRC TechName("CopyDepthToAlphaNoMask");
      GetUtils().ShBeginPass(CShaderMan::m_shPostDepthOfField, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);                                   
    }

    gcpRendD3D->FX_SetState( GS_NODEPTHTEST|GS_COLMASK_A ); 

    static CCryNameR ParamName("dofParamsFocus");
    GetUtils().ShSetParamPS(ParamName, pDofParams.vFocus);

    GetUtils().SetTexture(CTexture::s_ptexZTarget, 0, FILTER_POINT);  

    CTexture *pMaskTex = const_cast<CTexture *> (static_cast<CParamTexture*>(m_pMaskTex)->GetParamTexture());

    if(pMaskTex && fUseMask)
    {
      float fMaskW = pMaskTex->GetWidth();
      float fMaskH = pMaskTex->GetHeight();

      Vec4 pParamTexScale = Vec4(0, 0, fMaskW, fMaskH); 

      GetUtils().SetTexture(pMaskTex, 1, FILTER_LINEAR);  
    }

    GetUtils().DrawFullScreenQuad(CTexture::s_ptexBackBuffer->GetWidth(), CTexture::s_ptexBackBuffer->GetHeight());

    GetUtils().ShEndPass();                    

    // XENON-srgb notes: since render directly to framebuffer then resolve to non-srgb surface, to get gamma correction done in hw - also saves 1 redundant resolve		
    GetUtils().CopyScreenToTexture(CTexture::s_ptexBackBuffer);

    // Restore previous viewport
    gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight);     

    // Update back-buffer
    GetUtils().StretchRect(CTexture::s_ptexBackBuffer, CTexture::s_ptexBackBufferScaled[0]);
    GetUtils().StretchRect(CTexture::s_ptexBackBufferScaled[0], CTexture::s_ptexBackBufferScaled[1]);
  }

  Vec4 vParamsBlur = Vec4(fMaxCoC*0.5f, fMaxCoC, fBlurAmount, pDofParams.vFocus.w);
  PoissonDofRender( pDofParams.vFocus, vParamsBlur );

  gcpRendD3D->FX_Flush();

  PROFILE_SHADER_END    
  PROFILE_LABEL_POP( "DEPTH OF FIELD" );

  gRenDev->m_RP.m_FlagsShader_RT = nSaveFlagsShader_RT;
} 

/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////

void CDepthOfField::PoissonDofRender( const Vec4 &pFocusParams, const Vec4 &pBlurParams )
{
  GetUtils().TexBlurGaussian(CTexture::s_ptexBackBufferScaled[0], 1, 1, 1, false, 0, false, CTexture::s_ptexBackBufferScaledTemp[0]);

  ///////////////////////////////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////

  static CCryNameTSCRC TechDOFName("DepthOfField");
  GetUtils().ShBeginPass(CShaderMan::m_shPostDepthOfField, TechDOFName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);                    

  uint32 nRenderStates = GS_NODEPTHTEST;

  gcpRendD3D->FX_SetState( nRenderStates );          

  static CCryNameR Param1Name("dofParamsFocus");
  GetUtils().ShSetParamPS(Param1Name, pFocusParams);

  //Vec4 vParamsBlur=Vec4(fMaxCoC*0.5f, fMaxCoC, fBlurAmount, fBlurAmount);   
  static CCryNameR Param2Name("dofParamsBlur");
  GetUtils().ShSetParamPS(Param2Name, pBlurParams);    

  Vec4 vPixelSizes=Vec4(1.0f/(float)CTexture::s_ptexBackBuffer->GetWidth(),
    1.0f/(float)CTexture::s_ptexBackBuffer->GetHeight(),
    1.0f/(float)CTexture::s_ptexBackBufferScaled[1]->GetWidth(),
    1.0f/(float)CTexture::s_ptexBackBufferScaled[1]->GetHeight()); 
  static CCryNameR Param3Name("pixelSizes");
  GetUtils().ShSetParamPS(Param3Name, vPixelSizes);    

  GetUtils().SetTexture(CTexture::s_ptexBackBuffer, 0, FILTER_POINT);
  GetUtils().SetTexture(CTexture::s_ptexBackBufferScaled[0], 1);  

  GetUtils().DrawFullScreenQuad(CTexture::s_ptexBackBuffer->GetWidth(), CTexture::s_ptexBackBuffer->GetHeight()); 

  GetUtils().ShEndPass();                
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
void CDepthOfField::RenderHiQuality()
{	
	bool bEnabled = true;
	if ( !CRenderer::CV_r_usezpass || !CRenderer::CV_r_dof || CRenderer::CV_r_dof != 2)  
		bEnabled = false;

	float fTimeOfDayBlurAmount = m_pTimeOfDayBlurAmount->GetParam();
	if( (m_pBlurAmount->GetParam() <= 0.1f && m_pUserBlurAmount->GetParam() <= 0.1f && fTimeOfDayBlurAmount <= 0.1f))      
		bEnabled = false;

	if( !IsActive() && !m_pUserActive->GetParam() && !fTimeOfDayBlurAmount )
		bEnabled = false;

	if( !bEnabled )
		return;

	//UpdateBokehSamples();

	CTexture *pSceneSrc = CTexture::s_ptexHDRTarget;
	CTexture *pSceneTmp = CTexture::s_ptexSceneTarget;
	CTexture *pSceneTmpSec = CTexture::s_ptexSceneDiffuseAccMap;

	gRenDev->m_cEF.mfRefreshSystemShader("DepthOfField", CShaderMan::m_shPostDepthOfField);

	Vec4 vParamsFocus;
	int iTempX, iTempY, iWidth, iHeight;
	gcpRendD3D->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight);

	uint64 nSaveFlagsShader_RT = gRenDev->m_RP.m_FlagsShader_RT;
	// Enable corresponding shader variation
	gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0]|g_HWSR_MaskBit[HWSR_SAMPLE1]|g_HWSR_MaskBit[HWSR_SAMPLE2]|g_HWSR_MaskBit[HWSR_SAMPLE3]);

	//if( CRenderer::CV_r_colorgrading_levels && (fMinInput || fGammaInput || fMaxInput || fMinOutput ||fMaxOutput) )
	gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; // enable hdr version

	float fPrevDist = 0, fPrevMaxCoC = 0, fPrevFocusRange = 0, fPrevBlurAmount = 0, fPrevFocusMin = 0, fPrevFocusMax = 0;
	float fPrevFocusLimit = 0, fPrevUseMask = 0;

	float fTodFocusRange = m_pTimeOfDayFocusRange->GetParam();
	float fTodBlurAmount = m_pTimeOfDayBlurAmount->GetParam();

	float fFocusRange = m_pFocusRange->GetParam();
	float fMaxCoC = m_pMaxCoC->GetParam();  
	float fCenterWeigth = max(0.0f, m_pCenterWeight->GetParam());  
	float fBlurAmount = m_pBlurAmount->GetParam();

	//if( fBlurAmount < 0.01f)
	//return;

	PROFILE_SHADER_START

		CTexture *pSceneScaledTmp = CTexture::s_ptexHDRTargetScaledTmp[0];
	CTexture *pSceneScaledFarDof = CTexture::s_ptexHDRTargetScaled[0];
	SDynTexture *tpSceneScaledNearDof = new SDynTexture(pSceneScaledFarDof->GetWidth(), pSceneScaledFarDof->GetHeight(), pSceneScaledFarDof->GetDstFormat(), eTT_2D, FT_STATE_CLAMP | FT_USAGE_RENDERTARGET, "SceneScaledNearDofRT");
	tpSceneScaledNearDof->Update( pSceneScaledFarDof->GetWidth(), pSceneScaledFarDof->GetHeight() );

	if( !tpSceneScaledNearDof->m_pTexture)
	{
		SAFE_DELETE(tpSceneScaledNearDof);
		return;
	}


	bool bGameDof = IsActive();
	float fUserBlurAmount = m_pUserBlurAmount->GetParam();
	SDepthOfFieldParams pDofParams = GetParams();

	///////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////////
	//if( 0 ) 
	{  
		gcpRendD3D->FX_PushRenderTarget(0,  pSceneTmp, NULL); 
		gcpRendD3D->RT_SetViewport(0, 0, pSceneTmp->GetWidth(), pSceneTmp->GetHeight());        

		// Copy depth into backbuffer alpha channel

		float fUseMask = m_pUseMask->GetParam();
		if(pDofParams.bGameMode)
		{ 
			// Special case for gameplay
			if( fUseMask )        
			{
				static CCryNameTSCRC TechName("CopyDepthToAlphaBiased");
				GetUtils().ShBeginPass(CShaderMan::m_shPostDepthOfField, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);
			}
			else
			{
				static CCryNameTSCRC TechName("CopyDepthToAlphaBiasedNoMask");
				GetUtils().ShBeginPass(CShaderMan::m_shPostDepthOfField, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);            
			}
		}
		else
		{
			// For cinematics (simplified interface, using only focus distance/range)
			static CCryNameTSCRC TechName("CopyDepthToAlphaNoMask");
			GetUtils().ShBeginPass(CShaderMan::m_shPostDepthOfField, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);                                   
		}

		gcpRendD3D->FX_SetState(GS_NODEPTHTEST);  //|GS_COLMASK_A

		static CCryNameR ParamName("dofParamsFocus");
		GetUtils().ShSetParamPS(ParamName, pDofParams.vFocus);

		GetUtils().SetTexture(CTexture::s_ptexZTarget, 0, FILTER_POINT);  

		CTexture *pMaskTex = const_cast<CTexture *> (static_cast<CParamTexture*>(m_pMaskTex)->GetParamTexture());

		if(pMaskTex && fUseMask && bGameDof)
		{
			float fMaskW = pMaskTex->GetWidth();
			float fMaskH = pMaskTex->GetHeight();

			Vec4 pParamTexScale = Vec4(0, 0, fMaskW, fMaskH); 

			GetUtils().SetTexture(pMaskTex, 1, FILTER_LINEAR);  
			GetUtils().SetTexture(pSceneSrc, 2, FILTER_POINT);
		}
		else
			GetUtils().SetTexture(pSceneSrc, 1, FILTER_POINT);

		GetUtils().DrawFullScreenQuad(pSceneTmp->GetWidth(), pSceneTmp->GetHeight());

		GetUtils().ShEndPass();                    

		// Restore previous viewport
		gcpRendD3D->FX_PopRenderTarget(0);
		gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight);     

		// Update back-buffer
		GetUtils().StretchRect(pSceneTmp, pSceneScaledTmp);
	}

	//uint32 pBokehSamples[2] = { 32, 64 };
	//uint32 nBokehSampleCount = pBokehSamples[ max(0, min(CRenderer::CV_r_DofBokehQuality, 1)) ];

	//gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE1];
	//if( CRenderer::CV_r_DofBokehQuality > 0)
	//	gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1];

	///////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////////

	{
		gcpRendD3D->FX_PushRenderTarget(0, pSceneScaledFarDof,  0);		
		//gcpRendD3D->FX_PushRenderTarget(0, tpSceneScaledNearDof->m_pTexture,  0);		
		//gcpRendD3D->FX_PushRenderTarget(1, pSceneScaledFarDof,  0);		
		gcpRendD3D->RT_SetViewport(0, 0, pSceneScaledFarDof->GetWidth(), pSceneScaledFarDof->GetHeight());   

		CCryNameTSCRC TechDOFName("DofHiQualityNearFarSetup");
		GetUtils().ShBeginPass(CShaderMan::m_shPostDepthOfField, TechDOFName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);                    

		gcpRendD3D->FX_SetState(GS_NODEPTHTEST);          

		static CCryNameR Param1Name("dofParamsFocus");
		GetUtils().ShSetParamPS(Param1Name, vParamsFocus);

		Vec4 vParamsBlur=Vec4(fMaxCoC*0.5f, fMaxCoC, fBlurAmount, pDofParams.vFocus.w);   
		static CCryNameR Param2Name("dofParamsBlur");
		GetUtils().ShSetParamPS(Param2Name, vParamsBlur);    

		Vec4 vPixelSizes=Vec4(1.0f/(float)pSceneScaledFarDof->GetWidth(),
			1.0f/(float)pSceneScaledFarDof->GetHeight(),
			1.0f/(float)pSceneScaledTmp->GetWidth(),
			1.0f/(float)pSceneScaledTmp->GetHeight()); 

		static CCryNameR Param3Name("pixelSizes");
		GetUtils().ShSetParamPS(Param3Name, vPixelSizes);    


		static CCryNameR ParamBokehSamplesName("dofBokehSamples");
		//CShaderMan::m_shPostDepthOfField->FXSetPSFloat(ParamBokehSamplesName, &m_vBokehSamples[0], m_vBokehSamples.size());    

		GetUtils().SetTexture(pSceneScaledTmp, 0, FILTER_LINEAR);

		GetUtils().DrawFullScreenQuad(CTexture::s_ptexHDRTargetScaled[0]->GetWidth(), CTexture::s_ptexHDRTargetScaled[0]->GetHeight());

		GetUtils().ShEndPass();                    

		gcpRendD3D->FX_PopRenderTarget(0); 		
		//gcpRendD3D->FX_PopRenderTarget(1); 		
	}

	{
		gcpRendD3D->FX_PushRenderTarget(0, pSceneSrc,  0);		
		gcpRendD3D->RT_SetViewport(0, 0, pSceneSrc->GetWidth(), pSceneSrc->GetHeight());   

		static CCryNameTSCRC TechDOFName("DofHiQuality");
		GetUtils().ShBeginPass(CShaderMan::m_shPostDepthOfField, TechDOFName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);                    

		gcpRendD3D->FX_SetState(GS_NODEPTHTEST);          

		static CCryNameR Param1Name("dofParamsFocus");
		GetUtils().ShSetParamPS(Param1Name, vParamsFocus);

		Vec4 vParamsBlur=Vec4(fMaxCoC*0.5f, fMaxCoC, fBlurAmount, pDofParams.vFocus.w);   
		static CCryNameR Param2Name("dofParamsBlur");
		GetUtils().ShSetParamPS(Param2Name, vParamsBlur);    

		Vec4 vPixelSizes=Vec4(1.0f/(float)pSceneSrc->GetWidth(),
			1.0f/(float)pSceneSrc->GetHeight(),
			1.0f/(float)pSceneScaledFarDof->GetWidth(),
			1.0f/(float)pSceneScaledFarDof->GetHeight()); 

		static CCryNameR Param3Name("pixelSizes");
		GetUtils().ShSetParamPS(Param3Name, vPixelSizes);    

		static CCryNameR ParamBokehSamplesName("dofBokehSamples");
		//CShaderMan::m_shPostDepthOfField->FXSetPSFloat(ParamBokehSamplesName, &m_vBokehSamples[0], m_vBokehSamples.size());   

		GetUtils().SetTexture(pSceneTmp, 0, FILTER_LINEAR);    
		GetUtils().SetTexture(tpSceneScaledNearDof->m_pTexture, 1, FILTER_LINEAR);
		GetUtils().SetTexture(pSceneScaledFarDof, 2, FILTER_LINEAR);

		GetUtils().DrawFullScreenQuad(pSceneSrc->GetWidth(), pSceneSrc->GetHeight());

		GetUtils().ShEndPass();                    

		gcpRendD3D->FX_PopRenderTarget(0); 		
	}

	SAFE_DELETE(tpSceneScaledNearDof);

	gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight);   

	gcpRendD3D->FX_Flush();
	PROFILE_SHADER_END    

	gRenDev->m_RP.m_FlagsShader_RT = nSaveFlagsShader_RT;
}
